package com.sk.bilibili.handler.numHandler;

import com.sk.bilibili.utils.StringUtils;
import lombok.SneakyThrows;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

/**
 * @author 邵康
 * @date 2021/12/19 13:13
 */
// 同样只能继承 一层   使用 接口定义的方法 操作
public class ReflectNumHandler<T> extends BaseNumHandler<T>{

    private String fieldName;
    private Method getter;
    private Method setter;

    public ReflectNumHandler(String fieldName) {
        this.fieldName=fieldName;
        initMethod();
    }

    @SneakyThrows
    private void initMethod() {
        Type type = this.getClass().getGenericSuperclass();
        if(type instanceof ParameterizedType){
            ParameterizedType parameterizedType= (ParameterizedType) type;
            if(parameterizedType.getRawType().equals(ReflectNumHandler.class)){
                Class<?> clazz= (Class<?>) parameterizedType.getActualTypeArguments()[0];
                String baseName = StringUtils.upperFirst(fieldName);
                getter=clazz.getMethod("get"+baseName);
                setter=clazz.getMethod("set"+baseName,Integer.class);
                return;
            }
        }
        throw new RuntimeException("继承层次太深 或没有正确指定泛型或 参数类型不正确");
    }

    @SneakyThrows
    @Override
    public void postHandle(T data) {
        setter.invoke(data,(Integer)getter.invoke(data)+redisUtils.getNum(data,fieldName));
    }

    @Override
    public void beforeHandle(T data) {
        redisUtils.clearNum(data,fieldName);
    }

}
